using Cysharp.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class OtherBehaviour_CQD16 : AgvOtherBehaviour
{
    NdcInfo carData;

    GameObject pushPart, pushForward, pullBack;
    float pushSpeed;
    public OtherBehaviour_CQD16(GameObject pushPart, GameObject pushForward, GameObject pullBack, float pushSpeed = 0.01f)
    {
        this.pushPart = pushPart;
        this.pushForward = pushForward;
        this.pullBack = pullBack;
        this.pushSpeed = pushSpeed;
    }
    public override void OtherBehaviour(NdcInfo carData)
    {
        if (carData != null)
        {
            this.carData = carData;
            ChangePushStatus(carData.pushStatus);
        }
    }
    PushStatus previewPushStatus = PushStatus.None;

    public void ChangePushStatus(int pushStatus)
    {
        PushStatus currentPushStatus = PushStatus.None;
        switch (pushStatus)
        {
            case 0:
                currentPushStatus = PushStatus.PullBack;
                StartPull_UniTask();
                break;
            case 10:
                currentPushStatus = PushStatus.PullBack;
                break;
            case 60:
                currentPushStatus = PushStatus.PullBack;
                break;
            case 70:
                currentPushStatus = PushStatus.PullBack;
                break;
            case 80:
                currentPushStatus = PushStatus.PullBack;
                break;

            case 1:
                currentPushStatus = PushStatus.Doing;
                break;
            case 20:
                currentPushStatus = PushStatus.PushForward;
                break;
            case 30:
                currentPushStatus = PushStatus.PushForward;
                break;
            case 40:
                currentPushStatus = PushStatus.PushForward;
                break;
            case 50:
                currentPushStatus = PushStatus.PushForward;
                break;
        }
        if (currentPushStatus != previewPushStatus)
        {
            if (currentPushStatus == PushStatus.PushForward)
            {
                StartPush_UniTask();
            }
            else if (currentPushStatus == PushStatus.PullBack)
            {
                StartPull_UniTask();
            }
        }
        previewPushStatus = currentPushStatus;
    }
    CancellationTokenSource _PushOrPullCancellation = new();
    public void StartPush_UniTask()
    {
        _PushOrPullCancellation.Cancel();
        _PushOrPullCancellation.Dispose();
        _PushOrPullCancellation = new();

        Push_UniTask(_PushOrPullCancellation.Token);
    }

    private async void Push_UniTask(CancellationToken token)
    {
        while (pushPart.transform.position != pushForward.transform.position)
        {
            pushPart.transform.position = Vector3.MoveTowards(pushPart.transform.position, pushForward.transform.position, Time.deltaTime * pushSpeed);

            bool isCanceled = await UniTask.NextFrame(token).SuppressCancellationThrow();

            if (isCanceled)
            {
                MyLogger.Log($"AGV : {carData.agvId} Push is Cancelled");
                return;
            }
        }
    }

    public void StartPull_UniTask()
    {
        _PushOrPullCancellation.Cancel();
        _PushOrPullCancellation.Dispose();
        _PushOrPullCancellation = new();

        Pull_UniTask(_PushOrPullCancellation.Token);
    }

    private async void Pull_UniTask(CancellationToken token)
    {
        while (pushPart.transform.position != new Vector3(pullBack.transform.position.x, pushPart.transform.position.y, pullBack.transform.position.z))
        {
            pushPart.transform.position = Vector3.MoveTowards(pushPart.transform.position, new Vector3(pullBack.transform.position.x, pushPart.transform.position.y, pullBack.transform.position.z), Time.deltaTime * pushSpeed);
            bool isCanceled = await UniTask.NextFrame(token).SuppressCancellationThrow();
            if (isCanceled)
            {
                MyLogger.Log($"AGV : {carData.agvId} Pull is Cancelled");
                return;
            }
        }
    }
    public enum PushStatus
    {
        None,
        PushForward,
        PullBack,
        Doing
    }
    public override void Update()
    {
        base.Update();
    }
}
